﻿using System;
using System.ComponentModel;
using System.ServiceModel;
using System.Windows.Forms;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using RibbonEditor.Managers;
using Tanguy.WinForm.Utilities.DelegatesHelpers;

namespace RibbonEditor.Forms.Solutions
{
    public partial class SolutionPicker : Form
    {
        IOrganizationService innerService;
        MetadataManager innerMetadataManager;
        public Entity SelectedSolution { get; set; }

        public SolutionPicker(IOrganizationService service, MetadataManager mManager)
        {
            InitializeComponent();

            this.innerService = service;
            this.innerMetadataManager = mManager;
        }

        private void SolutionPicker_Load(object sender, EventArgs e)
        {
            BackgroundWorker worker = new BackgroundWorker();
            worker.DoWork += new DoWorkEventHandler(worker_DoWork);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
            worker.RunWorkerAsync();
        }

        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            this.FillList();
        }

        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            MethodInvoker mi = delegate
            {
                this.lstSolutions.Enabled = true;
                this.btnNewSolution.Enabled = true;
                this.btnProperties.Enabled = true;
                this.btnSolutionPickerValidate.Enabled = true;
            };

            if (this.InvokeRequired)
            {
                this.Invoke(mi);
            }
            else
            {
                mi();
            }
        }

        

        private void FillList()
        {
            try
            {
                ListViewDelegates.ClearItems(this.lstSolutions);

                EntityCollection ec = this.RetrieveSolutions();

                foreach (Entity solution in ec.Entities)
                {
                    ListViewItem item = new ListViewItem(solution["friendlyname"].ToString());
                    item.SubItems.Add(solution["version"].ToString());
                    item.SubItems.Add(((EntityReference)solution["publisherid"]).Name);
                    item.Tag = solution;

                    ListViewDelegates.AddItem(this.lstSolutions, item);
                }
            }
            catch (Exception error)
            {
                CommonDelegates.DisplayMessageBox(this, error.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);            
            }
        }

        private EntityCollection RetrieveSolutions()
        {
            try
            {
                QueryExpression qe = new QueryExpression("solution");
                qe.Distinct = true;
                qe.ColumnSet = new ColumnSet(true);
                qe.Criteria = new FilterExpression();
                qe.Criteria.AddCondition(new ConditionExpression("ismanaged", ConditionOperator.Equal, false));
                qe.Criteria.AddCondition(new ConditionExpression("isvisible", ConditionOperator.Equal, true));
                qe.Criteria.AddCondition(new ConditionExpression("uniquename", ConditionOperator.NotEqual, "Default"));
                qe.LinkEntities.Add(new LinkEntity("solution","solutioncomponent","solutionid","solutionid", JoinOperator.Inner));
                qe.LinkEntities[0].LinkCriteria = new FilterExpression();
                qe.LinkEntities[0].LinkCriteria.AddCondition(new ConditionExpression("componenttype", ConditionOperator.In, new object[] { 1, 50 }));
                
                return this.innerService.RetrieveMultiple(qe);
            }
            catch (Exception error)
            {
                if (error.InnerException != null && error.InnerException is FaultException)
                {
                    throw new Exception("Error while retrieving solutions: " + ((FaultException)error.InnerException).Message);
                }
                else
                {
                    throw new Exception("Error while retrieving solutions: " + error.Message);
                }
            }
        }

        private void btnNewSolution_Click(object sender, EventArgs e)
        {
            CreateSolutionDialog csDialog = new CreateSolutionDialog(this.innerService, this.innerMetadataManager);
            csDialog.StartPosition = FormStartPosition.CenterParent;

            if (csDialog.ShowDialog() == DialogResult.OK)
            {
                this.FillList();
            }
        }

        private void lstSolutions_DoubleClick(object sender, EventArgs e)
        {
            if (this.lstSolutions.SelectedItems.Count > 0)
            {
                this.SelectedSolution = (Entity)this.lstSolutions.SelectedItems[0].Tag;
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
        }

        private void btnProperties_Click(object sender, EventArgs e)
        {
            if (this.lstSolutions.SelectedItems.Count > 0)
            {
                //XmlNode node = (XmlNode)this.lstSolutions.SelectedItems[0].Tag;
                //CreateWebResourceDialog cwrDialog = new CreateWebResourceDialog(node);

                //cwrDialog.ShowDialog();
            }
        }

        private void btnSolutionPickerValidate_Click(object sender, EventArgs e)
        {
            if (this.lstSolutions.SelectedItems.Count > 0)
            {
                this.SelectedSolution = (Entity)this.lstSolutions.SelectedItems[0].Tag;
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
            else
            {
                MessageBox.Show(this, "Please select a solution!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        private void btnSolutionPickerCancel_Click(object sender, EventArgs e)
        {
            this.SelectedSolution = null;
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }

       
    }
}
